﻿#include "mainwindow.h"
#include"GameModel.h"
#include "ui_mainwindow.h"
#include<QPainter>
#include<QMouseEvent>
#include<math.h>
#include<QDebug>
#include<QMessageBox>
#include<QTimer>
#include<QDialog>
#include<QSound>
#include"choosemode.h"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //添加图标
    //"/pic/wuziqi.png"
    setWindowIcon(QIcon(":/pic/icon.png"));

    setMouseTracking(true);//调用鼠标移动监听
    //设置窗口标题
    setWindowTitle("五子棋");
    //设置窗口大小
    setFixedSize(MARGIN*2+BLOCK_SIZE*BOARD_GRAD_SIZE,
                 MARGIN*2+BLOCK_SIZE*BOARD_GRAD_SIZE);
    //设置菜单
    QMenuBar *bar = this->menuBar();
       //将菜单栏放入窗口中
       this->setMenuBar(bar);

       //创建菜单项
       QMenu * helpMenu = bar->addMenu("帮助");
       //创建菜单项
       QAction *back = helpMenu->addAction("返回");//给菜单项下面再添加项目
       connect(back,&QAction::triggered,this,[=](){
           //qDebug()<<"返回";
           fiveMode=new choosemode;
           //自身隐藏
           this->hide();
           //显示选择模式的场景
           fiveMode->show();
       });

    initGame();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::paintEvent(QPaintEvent *){
    QPainter painter(this);

    //绘制背景
    QPixmap pix;
    pix.load(":/pic/background.png");
    painter.drawPixmap(0,0,this->width(),this->height(),pix);
    //绘制棋盘
    painter.setRenderHint(QPainter::Antialiasing,true);//抗锯齿
    for(int i=0;i<BOARD_GRAD_SIZE+1;i++){
        //从左到右，第(i+1)条竖线
        painter.drawLine(MARGIN+BLOCK_SIZE*i,MARGIN,MARGIN+BLOCK_SIZE*i,size().height()-MARGIN);
        //从上到下，第(i+1)条横线
        painter.drawLine(MARGIN,MARGIN+BLOCK_SIZE*i,size().width()-MARGIN,MARGIN+BLOCK_SIZE*i);


    }

    //绘制选中点
    QBrush brush;
    brush.setStyle(Qt::SolidPattern);
    //绘制落子标记(防止鼠标出框越界)
    if(clickPosRow>0&&clickPosRow<BOARD_GRAD_SIZE&&
            clickPosCol>0&&clickPosCol<BOARD_GRAD_SIZE&&
            game->gameMapVec[clickPosRow][clickPosCol]==0){
        if(game->playerFlag)
            brush.setColor(Qt::black);//黑子
        else
            brush.setColor(Qt::white);
        painter.setBrush(brush);
        //绘制矩形左上角x坐标 y坐标 长 宽
        painter.drawRect(MARGIN+BLOCK_SIZE*clickPosCol-MARK_SIZE/2,MARGIN+BLOCK_SIZE*clickPosRow-MARK_SIZE/2,Preview_MARGIN,Preview_MARGIN);
    }

    //绘制棋子
    for(int i=0;i<BOARD_GRAD_SIZE;i++){
        for(int j=0;j<BOARD_GRAD_SIZE;j++){
            if(game->gameMapVec[i][j]==1){
            brush.setColor(Qt::black);
            painter.setBrush(brush);
            painter.drawEllipse(MARGIN/2+BLOCK_SIZE*j,MARGIN/2+BLOCK_SIZE*i,MARGIN,MARGIN);
            }
            else if(game->gameMapVec[i][j]==-1){
                brush.setColor(Qt::white);
                painter.setBrush(brush);
                painter.drawEllipse(MARGIN/2+BLOCK_SIZE*j,MARGIN/2+BLOCK_SIZE*i,MARGIN,MARGIN);
            }
        }
        //判断输赢
        if(clickPosRow>0&&clickPosRow<BOARD_GRAD_SIZE&&//判断落子位置是否规范
                clickPosCol>0&&clickPosCol<BOARD_GRAD_SIZE&&
                (game->gameMapVec[clickPosRow][clickPosCol]==1||//判断落子位置是黑或者白
                 game->gameMapVec[clickPosRow][clickPosCol]==-1)){
            if(game->isWIn(clickPosRow,clickPosCol)&&game->gameStatus==PLAYING){
                game->gameStatus=WIN;
                //QSound::play(":sound/win.wav");
                QString str;
                if(game->gameMapVec[clickPosRow][clickPosCol]==1){
                    str="黑棋";
                    //失败音效
                    QSound* win=new QSound(":/pic/win.wav",this);
                    win->play();

                }
                else if(game->gameMapVec[clickPosRow][clickPosCol]==-1){
                    str="白棋";
                    //胜利音效
                    QSound* lose=new QSound(":/pic/lose.wav",this);
                    lose->play();

                }
                QMessageBox::StandardButton btnValue=QMessageBox::information(this,"五子棋对战",str+"胜利");
                //重置游戏状态，否则容易死循环
                if(btnValue==QMessageBox::Ok){
                    game->startGame(game_type);
                    game->gameStatus=PLAYING;
                }


            }
        }
    }
}
void MainWindow::initGame(){
    game=new GameModel;
    initAIGame();
}
void MainWindow::initAIGame(){
    game_type=AI;
    game->gameStatus=PLAYING;
    //在数据模型中初始化功能
    game->startGame(game_type);
    update();
}
void MainWindow::mouseMoveEvent(QMouseEvent * event){
    //通过鼠标的靠近判断落子标记
    int x=event->x();
    int y=event->y();

    //棋盘边缘不能落子 当落子在棋盘范围内才执行
    if(x>=MARGIN+BLOCK_SIZE/2&&
            x<size().width()-MARGIN-BLOCK_SIZE/2&&
            y>=MARGIN+BLOCK_SIZE/2&&
            y<size().height()-MARGIN-BLOCK_SIZE/2){
        //获取一个最近的左上角的点
        //add by rock
        int col=(x-MARGIN)/BLOCK_SIZE;
        int row=(y-MARGIN)/BLOCK_SIZE;

        int leftTopPosX=MARGIN+BLOCK_SIZE*col;
        int leftTopPosY=MARGIN+BLOCK_SIZE*row;

        //根据 距离算出合适的点击位置，一共四个点，根据半径距离选择最近的
        clickPosRow=-1;
        clickPosCol=-1;
        int len=0;//计算完后取整

         selectPos=false;

         //确定一个误差在范围内的点，且只能确定一个
         len=sqrt(pow((x-leftTopPosX),2)+pow((y-leftTopPosY),2));
         if(len<POS_OFFSET){
             clickPosRow=row;
             clickPosCol=col;
             //只有在该位置没棋子的时候才能下 左上角
             if(game->gameMapVec[clickPosRow][clickPosCol]==0){
                 selectPos=true;
             }
         }
         //判断右上角
         len=sqrt(pow((x-leftTopPosX-BLOCK_SIZE),2)+pow((y-leftTopPosY),2));
         if(len<POS_OFFSET){
             clickPosRow=row;
             clickPosCol=col+1;

             if(game->gameMapVec[clickPosRow][clickPosCol]==0){
                 selectPos=true;
             }
         }
         //判断左下角
         len=sqrt(pow((x-leftTopPosX),2)+pow((y-leftTopPosY-BLOCK_SIZE),2));
         if(len<POS_OFFSET){
             clickPosRow=row+1;
             clickPosCol=col;

             if(game->gameMapVec[clickPosRow][clickPosCol]==0){
                 selectPos=true;
             }
         }
         //判断右下角
         len=sqrt(pow((x-leftTopPosX-BLOCK_SIZE),2)+pow((y-leftTopPosY-BLOCK_SIZE),2));
         if(len<POS_OFFSET){
             clickPosRow=row+1;
             clickPosCol=col+1;

             if(game->gameMapVec[clickPosRow][clickPosCol]==0){
                 selectPos=true;
             }
         }
    }
    //确定了一个点后 刷新 调用绘图
    update();
}
void MainWindow::mouseReleaseEvent(QMouseEvent *){

    if(selectPos==false){//如果没有选成功即位置不恰当，就返回重选
        return;
    }else{
        //如果选成功 在落子成功之前，要把落子标记重新设置为false，为下一次做准备
        selectPos=false;
    }

    //"下"一个人选定的棋子
    chessOneByPerson();

    if(game_type==AI){//人机模式
        //AI 下棋
        QTimer::singleShot(AI_THINK_TIME,this,SLOT(chessOneByAI()));
    }
}

void MainWindow::chessOneByPerson(){
    //根据当前存储的坐标下子
    //只有有效点击才下子，而且该处没有子
    if(clickPosRow!=-1&&clickPosCol!=-1&&game->gameMapVec[clickPosRow][clickPosCol]==0){
        //在游戏的数据模型中落子
        game->actionByPerson(clickPosRow,clickPosCol);
        //播放落子音效
        QSound* personChessOne=new QSound(":/pic/stone.wav",this);
        personChessOne->play();
        //重绘
        update();
    }
}

void MainWindow::chessOneByAI(){
    game->actionByAI(clickPosRow,clickPosCol);
    //QSound::play(":sound/chessone.wav");
    QSound* aiChessOne=new QSound(":/pic/stone.wav",this);
    aiChessOne->play();
    update();
}

void MainWindow::changeType(){
    if(game_type==AI)
        game_type=TwoMan;
    else
        game_type=AI;
}
